-
-
Notifications
You must be signed in to change notification settings - Fork 568
feat: Add Support for @oneOf
Input Object Directive
#1715
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
- add oneOfDirective definition, allowed on INPUT_OBJECT - add isOneOf to InputObjectType config - update BuldSchema to account for oneOf directive - add OneOfInputObjectsRule to validation rules
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice work! Happy to include this once polished.
Co-authored-by: Benedikt Franke <[email protected]>
- address PR review suggestions
…e fields - removed test and corresponding InvariantViolation that oneOf input types must not have deprecated fields. This was a mistake. I think in my mind I was thinking that if only 1 field was defined it should not be deprecated, but this doesn't match that intent and that's not part of the spec from what I can tell anyway so I've removed it
@spawnia thanks so much for the fast and thoughtful review! I pushed up some changes based on your feedback. Let me know if you see anything else that needs addressed. Thanks! 🙌 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nicely done! Thanks for working with me to add the final polish for this feature.
Released with https://github.com/webonyx/graphql-php/releases/tag/v15.21.0. Thank you @jasonbahl for your excellent work on this. |
@jasonbahl thanks for this amazing Pr. Could it be that SchemaPrinter::doPrint does not support dumping the |
Because if I understand the RFC correctly, it should add the input PetInput @oneOf {
cat: CatInput
dog: DogInput
fish: FishInput
} Currently there is only a test that guards that the directive is declared on the schema. But no test for the input object type. |
@ruudk thanks for calling this out. I do see a test in graphql-js for this (https://github.com/graphql/graphql-js/blob/8dc295551f9a64276442ef850943794db6bcaa4a/src/utilities/__tests__/printSchema-test.ts#L506-L521). I will follow up with a test for this case. |
@jasonbahl Another issue I noticed, is that on the Introspection query result, the |
Add Support for
@oneOf
Input Object DirectiveSummary
This PR implements the
@oneOf
input object directive to match the GraphQL.js reference implementation (v16.11.0) and align with the GraphQL specification RFC #825.The
@oneOf
directive enables input objects where exactly one field must be provided, addressing the common pattern of needing "input unions" in GraphQL schemas.Implementation Details
Core Type System Changes
InputObjectType
: AddedisOneOf
property with proper type annotations,isOneOf()
method, andvalidateOneOfConstraints()
for spec compliance validationDirective
: Added@oneOf
directive definition withINPUT_OBJECT
locationIntrospection
: AddedisOneOf
field to__Type
introspection objectValidation & Coercion
OneOfInputObjectsRule
: New validation rule ensuring exactly one field is provided in OneOf input objectsValue::coerceInputValue()
for runtime coercion errorsGraphQL.js Compatibility & Spec Alignment
Matching GraphQL.js v16.11.0
This implementation aligns with the GraphQL.js reference implementation, following the same patterns for:
isOneOf
property)isOneOf
field)Enhanced Spec Compliance
Based on GraphQL.js PR #4195 and spec RFC #825, we've implemented additional validation:
Test Coverage
This implementation includes comprehensive test coverage in
tests/Type/OneOfInputObjectTest.php
:Basic OneOf Type Definition
Query Validation
Runtime Coercion Validation
Value::coerceInputValue()
Edge Cases and Error Scenarios
Corresponding GraphQL.js Tests
For reference, test coverage matches the GraphQL.js implementation found in:
src/execution/__tests__/oneof-test.ts
src/utilities/__tests__/coerceInputValue-test.ts
(lines ~309-411)src/validation/__tests__/ValuesOfCorrectTypeRule-test.ts
(lines ~877+)src/type/__tests__/validation-test.ts
src/type/__tests__/introspection-test.ts
Breaking Changes
None. This is a purely additive feature that maintains full backward compatibility.
Migration Guide
No migration required. Existing schemas continue to work unchanged. To use OneOf:
Validation Results